package com.dotflat.util;

import com.dotflat.util.excelUtil.StringUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;

public class Base64ToFile {
    //BASE64解码成File文件
    public static File base64ToFile(String base64, String fileName) {
        File file = null;
        //创建文件目录
        String filePath = Base64ToFile.class.getClassLoader().getResource("").getPath();
        File  dir=new File(filePath);
        if (!dir.exists() && !dir.isDirectory()) {
            dir.mkdirs();
        }
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        try {
            //截取base64头部，获取文件类型
            String fileType =".jpg";
            //去掉头部，防止转换文件后打开显示文件损坏
            base64 = base64.substring(base64.indexOf(",")+1);
//            Decoder decoder = Base64.getDecoder();
//            byte[] bytes = decoder.decode(s);

            byte[] bytes = java.util.Base64.getDecoder().decode(base64);

            file=new File(filePath+"/"+fileName+fileType);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return file;
    }
    /**
     * 标准 Base64 字符串转 MultipartFile
     * @param base64Str 预处理后的标准 Base64 字符串（无前缀、无非法字符）
     * @param fileName 文件名（含后缀，如 "checkin_123_1694567890.jpg"）
     * @return MultipartFile 实例
     * @throws IOException 解码或流操作异常
     */
    public static MultipartFile base64ToMultipartFile1(String base64Str, String fileName) throws IOException {
        // 1. 基础校验
        if (StringUtils.isBlank(base64Str)) {
            throw new IllegalArgumentException("Base64 字符串不能为空");
        }
        if (StringUtils.isBlank(fileName)) {
            throw new IllegalArgumentException("文件名不能为空");
        }

        // 2. 标准 Base64 解码（用 Apache Commons Codec，兼容边缘场景）
        byte[] imageBytes;
        try {
            imageBytes = Base64.decodeBase64(base64Str);
        } catch (Exception e) {
            throw new IOException("Base64 解码失败：" + e.getMessage(), e);
        }

        // 3. 验证解码结果（避免空图片）
        if (imageBytes.length == 0) {
            throw new IOException("Base64 解码后图片字节为空");
        }

        // 4. 推断 MIME 类型（根据文件名后缀，适配 JPG/PNG/GIF）
        String contentType = getContentTypeByFileName(fileName);

        // 5. 转换为 InputStream 并构建 MultipartFile
        try (InputStream inputStream = new ByteArrayInputStream(imageBytes)) {
            return new MockMultipartFile(
                    "file",          // 表单参数名（无实际意义，匹配前端即可）
                    fileName,        // 文件名（含后缀）
                    contentType,     // MIME 类型（确保 OSS 正确识别图片格式）
                    inputStream      // 图片字节流
            );
        }
    }

    /**
     * 辅助方法：根据文件名后缀推断 MIME 类型
     */
    private static String getContentTypeByFileName(String fileName) {
        String lowerFileName = fileName.toLowerCase();
        if (lowerFileName.endsWith(".jpg") || lowerFileName.endsWith(".jpeg")) {
            return "image/jpeg";
        } else if (lowerFileName.endsWith(".png")) {
            return "image/png";
        } else if (lowerFileName.endsWith(".gif")) {
            return "image/gif";
        } else {
            return "image/*"; // 未知格式默认按图片处理
        }
    }

    public static MultipartFile base64ToMultipartFile(String base64, String fileName) {

        base64 = base64.substring(base64.indexOf(",")+1);

        byte[] bytes = Base64.decodeBase64(base64);

        BASE64DecodedMultipartFile file = new BASE64DecodedMultipartFile(bytes, fileName);

        return file;
    }

    //File转MultipartFile
    public static MultipartFile getMultipartFile(File file) {
        FileItem item = new DiskFileItemFactory().createItem("file"
                , MediaType.MULTIPART_FORM_DATA_VALUE
                , true
                , file.getName());
        try (InputStream input = new FileInputStream(file);
             OutputStream os = item.getOutputStream()) {
            // 流转移
            IOUtils.copy(input, os);
        } catch (Exception e) {
            throw new IllegalArgumentException("Invalid file: " + e, e);
        }

        return new CommonsMultipartFile(item);
    }


    public static String encodeToString(BufferedImage image, String type) {
        String imageString = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        try {
            ImageIO.write(image, type, bos);
            byte[] imageBytes = bos.toByteArray();

            imageString = Base64.encodeBase64URLSafeString(imageBytes);

            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return imageString;
    }

    public static BufferedImage decodeToImage(String base64) {

        BufferedImage image = null;
        byte[] imageByte;
        try {
//            BASE64Decoder decoder = new BASE64Decoder();
            base64 = base64.substring(base64.indexOf(",")+1);
            imageByte = Base64.decodeBase64(base64);
            ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
            image = ImageIO.read(bis);
            bis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return image;
    }

}
